#include "app_device.h"

#define BUFFER_SIZE 1024
#define POOL_SIZE 10

typedef struct
{
    bool is_running;       // 表示设备是否在运行
    buffer_t *down_buffer; // 下行缓冲区
    buffer_t *up_buffer;   // 下行缓冲区

    void (*mqtt_recv_cb)(char *data, int dataLen); // mqtt客户端接收到数据的回调函数

    void (*upload_task)(void *); // 数据上传任务
    void *upload_task_args;      // 数据上传任务参数

    void (*modbus_rw_task)(void *); // modbus读写任务
    void *modbus_rw_task_args;      // modbus读写任务参数
} device_handle;

static device_handle *device;

void mqtt_recv_cb(char *data, int dataLen);
void upload_task(void *);
void modbus_rw_task(void *);
device_handle_t app_device_init(void)
{
    if (device)
    {
        return (device_handle_t)device;
    }

    device = malloc(sizeof(device_handle));

    device->is_running = false;
    device->down_buffer = app_buffer_init(BUFFER_SIZE);
    device->up_buffer = app_buffer_init(BUFFER_SIZE);

    // 1. 初始化mqtt
    device->mqtt_recv_cb = mqtt_recv_cb;
    gate_status_t status = app_mqtt_init(device->mqtt_recv_cb);
    if (status != OK)
    {
        app_buffer_deInit(device->down_buffer);
        app_buffer_deInit(device->up_buffer);
        free(device);
        log_fatal("mqtt初始化失败, 导致设备初始化失败");
        return NULL;
    }
    // 2. 线程池的初始化
    status = app_pool_init(POOL_SIZE);
    if (status != OK)
    {
        app_buffer_deInit(device->down_buffer);
        app_buffer_deInit(device->up_buffer);
        app_mqtt_deInit();
        free(device);
        log_fatal("线程池初始化失败, 导致设备初始化失败");
        return NULL;
    }

    device->upload_task = upload_task;
    device->upload_task_args = NULL;

    device->modbus_rw_task = modbus_rw_task;
    device->modbus_rw_task_args = NULL;

    status = app_pool_add_task(device->upload_task, device->upload_task_args);
    if (status != OK)
    {
        app_buffer_deInit(device->down_buffer);
        app_buffer_deInit(device->up_buffer);
        app_mqtt_deInit();
        app_pool_deInit();
        free(device);
        log_fatal("添加上传任务失败, 导致设备初始化失败");
        return NULL;
    }

    status = app_pool_add_task(device->modbus_rw_task, device->modbus_rw_task_args);
    if (status != OK)
    {
        app_buffer_deInit(device->down_buffer);
        app_buffer_deInit(device->up_buffer);
        app_mqtt_deInit();
        app_pool_deInit();
        free(device);
        log_fatal("添加上传任务失败, 导致设备初始化失败");
        return NULL;
    }

    // 4. modubs 模块初始化 TODO
    status = app_modbus_init();
    if (status != OK)
    {
        app_buffer_deInit(device->down_buffer);
        app_buffer_deInit(device->up_buffer);
        app_mqtt_deInit();
        app_pool_deInit();
        free(device);
        log_fatal("modbus 模块初始化失败");
        return NULL;
    }

    device->is_running = true;
    return (device_handle_t)device;
}

void app_device_deInit(void)
{
    app_buffer_deInit(device->down_buffer);
    app_buffer_deInit(device->up_buffer);
    app_mqtt_deInit();
    app_pool_deInit();
    app_modbus_deInit();
    free(device);
}

bool app_device_is_running(void)
{
    return device->is_running;
}

void app_device_set_is_running(bool is_running)
{
    device->is_running = is_running;
}

/**
 * @brief mqtt收到数据的回调函数
 *
 * @param data
 * @param dataLen
 */
void mqtt_recv_cb(char *data, int dataLen)
{
    if (data == NULL || dataLen <= 0)
    {
        log_warn("收到mqtt数据为空");
        return;
    }
    log_debug("收到mqtt数据: %s", data);
    app_buffer_write(device->down_buffer, (uint8_t *)data, dataLen);
}

/**
 * @brief 上传数据任务
 *
 * @param args
 */
void upload_task(void *args)
{
    uint8_t data[256];
    while (1)
    {
        memset(data, 0, sizeof(data));
        uint8_t real_len = app_buffer_read(device->up_buffer, data, sizeof(data));
        if (real_len > 0)
        {
            log_info("从上行缓冲区读到数据: %.*s", real_len, data);
            data[real_len] = '\0'; // abcdefxxxxxxx
                                   // abc'\0'efxxxxx
            app_mqtt_send(data);
        }
    }
}

/**
 * @brief modbus读写任务
 *
 * @param args
 */
void modbus_rw_task(void *args)
{
    uint8_t data[256];
    while (1)
    {
        memset(data, 0, sizeof(data));
        uint8_t real_len = app_buffer_read(device->down_buffer, data, sizeof(data));
        if (real_len > 0)
        {
            log_info("从下行缓冲区读到数据: %.*s", real_len, data);
            msg_t msg;
            app_msg_json_2_msg(data, &msg);
            // 打印msg内容
            log_info("msg: %s, %s, %d, %d, %s", msg.action, msg.connType, msg.motorId, msg.motorSpeed, msg.status);
            // TODO把数据通过modbus发送出去
            if (strcmp(msg.action, "set") == 0)
            {
                // modbus函数1 (写保持寄存器) TODO
                app_modbus_writeSingleHoldRegister(msg.motorId, (uint16_t)msg.motorSpeed);
            }
            else if (strcmp(msg.action, "get") == 0)
            {

                // modbus函数2(读输入寄存器) TODO
                gate_status_t err = app_modbus_readSigleInputRegister(msg.motorId, &msg.motorSpeed);

                if (err == OK)
                {
                    msg.status = "ok";
                }
                else
                {
                    msg.motorSpeed = 0;
                    msg.status = "error";
                }
                memset(data, 0, sizeof(data));
                app_msg_msg_2_json(&msg, data);
                app_buffer_write(device->up_buffer, data, strlen(data));
            }
        }
    }
}
